<?php
namespace common\models\pay;

use common\models\userFund\UserWithdrawOrder;
use common\services\pay\alipay\aop\AlipayConfig;
use common\services\pay\alipay\aop\AopCertClient;
use common\services\pay\alipay\aop\request\AlipayFundTransCommonQueryRequest;
use common\services\pay\alipay\aop\request\AlipayFundTransToaccountTransferRequest;
use common\services\pay\alipay\aop\request\AlipayFundTransUniTransferRequest;
use common\services\pay\alipay\aop\request\AlipayTradeFastpayRefundQueryRequest;
use common\services\pay\alipay\aop\request\AlipayTradeRefundRequest;
use common\models\coin\CoinRechargeOrder;
use common\models\shop\Goods;
use common\models\shop\GoodsOrder;
use common\models\Status;
use common\models\user\User;
use common\models\userFund\UserRechargeOrder;
use common\models\userLevel\UserLevelOrder;
use common\services\pay\alipay\aop\request\AlipayTradeAppPayRequest;
use common\services\pay\alipay\aop\request\AlipayTradePagePayRequest;
use common\services\pay\alipay\aop\request\AlipayTradeWapPayRequest;
use common\services\pay\alipay\aop\AopClient;
use stdClass;
use yii\base\Exception;
use Yii;
use api\modules\v1\models\Common;
/**
 * This is the model class for table "goods".
 *
 * @property int $id
 * @property string $name
 */
class Alipay extends Common
{

    /**
     * 注意：异步通知地址和同步跳转地址都必须是在线可以访问的地址。
     *      私钥为之前生成器中生成的私钥，公钥则可以通过网站上查看
     */

    //应用ID,您的APPID。
    public $app_id;

    //商户私钥，您的原始格式RSA私钥 开头结尾回车都不要  去头去尾去回车  只要一条字符串
    public $merchant_private_key = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCAhpchbVAVn3aamhMR/RXFeZgSB981KMJXiX4meg1+4QGVZYaLZUqbPMH/3EHybJxpWuKlxiz45xDQQhR721YDJ8lNAnP1uXHHT/NlScdwHEnCathvwFvxhmKCw2XNHzkdVvxTDydimeOUcKECWEZ5OPLpfYsuo11pyXwXurHexM9g6lEaCiLwDfCI6aVKqQohBi19F9j81AFmUdWJiexRzshKp28FoBvuKLsIaKXCrjbisu+kNPtUNvWYCVP08ByXc0dcekiJe7eArHI/CdpjvqHX4S2C7nWyEf649mHNnYjhUyyrhl1DSSPlfbEnUYOjV5zmuZSVB4JNxr5fothHAgMBAAECggEABDtqUpF056FemGymYBtDUkNUvJNByFBVReijHMU8GId0M+Up7wEg2cfAY5pvGXp2FAoIGIlUBcYmCZWDcyifxm7S9BQ2mUrH8lYxn440YP6tdxdplRRycpuINuIUQhLbIJoyqNGA7IBAvCyRQLCDcY5sgT+/C4QZmVgnG+jr3nf0oBu8xb3nqZW+QfFO39HUiOz2qwxjtI3x3UO96qyHFbMB02VrN4rlvnc6g483Oi7MREaWblbrfhjTRApUpCCCkuW6FbPHoYkTiNCGJk04qIcPQRGzZj/Te1ExJ4XwjRgoQeV3jqNBnpGZFCe3UdzqMZDp2N+x5dv2fczp4CgWMQKBgQC79yqLkSjq3Ydtq5XjqOi0wSwJh9wcoiSPYZcVF9Ztg5YwDs+77Qdj/PJimKg2mEfGzJBzHLyPPjmccHMkg9rOlsmpJNbLZG/J7Mj1gV+m0QwEQdpeQrEVjvGsbwjbqz6a6fzcb6tn3XSu3yEhPzxvxTuMjxGsEk4yEo4EB3SE5QKBgQCvC8CdvMI1hecX5ig90hFu6JJMw8IrwL9KukcRTKLqfkExN2yfw6Uj+Dbw5izEaYHoAtDJSlXNek/AfvHsPmk132k0d/OGASMNYg7Kdo/9RWKvmi8WbxI6Cl8jduB3TTrxhMZdCILn5RekgWdNDNRMwI73N+r12ZOMSQ2V6s9huwKBgC/A6bQvmt+gjGmWcCw4m3ZgpVl+hLNZlkQ/HO0k8zs7dQqcmLY7z+bdOo9GDWZhZcrh6cj1Agq6WlSeVQJv5UUbFfy8+T0PNT9twthsl+p/rbffKyVLeEXr3QZb5zo31V3yGGXAkSGAJ8bNtVMHB8m1qB1bs7etpuQdxqrLYhTpAoGBAI3Cs8xK+PFFrwCQ2ZgvTwUF/q2Cf/bVE1Zeg32EFhBYDU3hd+vvEweNVllD3491bspJtXK+67wLyRi49g2AAc6qTtY6KpMkypFlD1tyJ2xSy/gwot/FNfqhOalL9b9IYWsFP2xKn1FUHBCS5+jjce9yppWZyIQwH6kl5IW78xVPAoGAAbWD26GTLILDSPdXzQ80zCXBgIL3elD2r/h6gHaP5KddbsJWjud/DfwpfwfwCECQS69RnKBb4BOOeAxElevnR77+/z69VAD65TadoFPKR7EAAHVyKz0n8NjYLHtgGEBfA/eWslx7qZBuZ7wWdHPVulBoB8Wd6XzmnMGWAzY8muE=";

    //异步通知地址  该选项必须和支付宝配置中的 应用网关一致
    public $notify_url = "http://api.linyunpeisong.com/v1/notify/alipay-notify"; //林云配送

    //同步跳转   该选项必须和支付宝配置中的 授权回调地址一致
    public $return_url = "http://api.linyunpeisong.com";//林云配送

    //编码格式
    public $charset = "UTF-8";

    //签名方式
    public $sign_type = "RSA2";

    //支付宝网关 固定值
    public $gatewayUrl = "https://openapi.alipay.com/gateway.do";

    //支付宝公钥,查看地址：https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。  一行字符串
    public $alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlkvRyMfaksyVqljn1JlHQo4DqVTnRR1LNr78gf1n27UrNJFiZm4jyN4o3HXzvduSnZDZxqGRQDORV45h+MYyMQMib6Ph0ONdvkOaypR3PeBpSFK9XMvO2YUpSTL982fG02EchYk+b4RTc1GGVqv5ne+Ej5Bt7O0ZUU+D7+VjXXQhbGXJKRqEnUoAFjYM4VdMadkGUsTgLqD80HLSDCYTnf1CCQED87U4bG3hioMwViUrn5og/dGGwow6PgLK4zXPJ2LGFxLmyJMiuOEyVEO4LuQvuWl3RZnR8EO+mOx9DHXOEfGlEuSdnwh7PgUh2iwRAmXUB2TdU7JxgeuUa8AnWwIDAQAB";

    //调用的接口版本，固定为1.0
    public $version = '1.0';

    //format 仅支持json
//    public $format = 'JSON';
    public $format = 'json';

    //销售产品码，与支付宝签约的产品码名称。

    public $project_code ;

    const projectCodeMap = [
        'web' => 'FAST_INSTANT_TRADE_PAY', //电脑网站支付
        'h5' => 'QUICK_WAP_WAY', //手机网站快捷支付
        'app' => 'QUICK_MSECURITY_PAY', //APP网站快捷支付
    ];

    # 新版支付
    public $alipayCertPublicRas2KeyCert;
    public $alipayAppPublicKeyCert;
    public $alipayRootKCert;

    public function __construct(array $config = [])
    {
//        $aop = new AopCertClient();
//        $alipayCertPath="支付宝公钥证书绝对路径";
//        $alipayCertPath=Yii::$app->params['ALIPAY_CERT_PUBLIC_RSA2_KEY_CERT'];
////调用getPublicKey获取支付宝公钥
//        $alipayrsaPublicKey = $aop->getPublicKey($alipayCertPath);
////输出
//       var_dump($alipayrsaPublicKey);die;

        parent::__construct($config);
        $this->app_id = Yii::$app->params['ALIPAY_APP_ID'];
        $this->merchant_private_key = Yii::$app->params['ALIPAY_MERCHANT_PRIVATE_KEY'];
        $this->alipay_public_key = Yii::$app->params['ALIPAY_PUBLIC_KEY'];
        $this->notify_url = Yii::$app->params['ALIPAY_NOTIFY_URL'];
        $this->return_url = Yii::$app->params['ALIPAY_RETURN_URL'];
        $this->gatewayUrl = Yii::$app->params['ALIPAY_GATEWAY_KEY'];

        $this->alipayCertPublicRas2KeyCert = Yii::$app->params['ALIPAY_CERT_PUBLIC_RSA2_KEY_CERT'];
        $this->alipayAppPublicKeyCert = Yii::$app->params['ALIPAY_APP_CERT_PUBLIC_KEY_CERT'];
        $this->alipayRootKCert = Yii::$app->params['ALIPAY_ROOT_CERT'];
    }

    /**
     * 商场支付订单
     * @param $orderNumber
     * @param string $type
     * @return \common\pay\alipay\aop\提交表单HTML文本|string
     *
     */
    public function payGoods($orderNumber, $type = 'app') {

        $orderInfo = GoodsOrder::getOneByWhere(['order_number' => $orderNumber]);
        $bizContent = [
            "body" => "龙邻生活。",               //对一笔交易的具体描述信息
            "subject" => "龙邻生活-支付订单",         //订单标题
            "out_trade_no" => $orderNumber,         //唯一平台订单号
            "total_amount" => sprintf("%.2f", $orderInfo['real_money']),//订单总金额 元为单位 100.00 保留两位小数
//            "total_amount" => '0.01',               //订单总金额 元为单位 100.00 保留两位小数
            'passback_params' => UrlEncode('type=goods'),
            "product_code" => '',                   //固定值
        ];

        return $this->payForm($bizContent, $type);
    }

    /**
     * 充值订单
     * @param $orderNumber
     * @param string $type
     * @return \common\pay\alipay\aop\提交表单HTML文本|string
     * @throws Exception
     */
    public function payRecharge($orderNumber, $type = 'app') {

        $orderInfo = UserRechargeOrder::getOneByWhere(['order_number' => $orderNumber]);
        $bizContent = [
            "body" => "龙邻生活。",//对一笔交易的具体描述信息
            "subject" => "龙邻生活-充值订单",         //订单标题
            "out_trade_no" => $orderNumber,//唯一平台订单号
            "total_amount" => $orderInfo['money'],//订单总金额 元为单位 100.00 保留两位小数
//            "total_amount" => '0.01',//订单总金额 元为单位 100.00 保留两位小数
            'passback_params' => UrlEncode('type=recharge'),
            "product_code" => '',  //固定值
        ];

//        var_dump($bizContent);die;
        return $this->payForm($bizContent, $type);
    }

    /**
     * 级别订单
     * @param $orderNumber
     * @param string $type
     * @return \common\pay\alipay\aop\提交表单HTML文本|string
     *
     */
    public function payLevel($orderNumber, $type = 'app') {

        $orderInfo = UserLevelOrder::getOneByWhere(['order_number' => $orderNumber]);
        $bizContent = [
            "body" => "龙邻生活。",               //对一笔交易的具体描述信息
            "subject" => "龙邻生活-购买会员",         //订单标题
            "out_trade_no" => $orderNumber,         //唯一平台订单号
            "total_amount" => sprintf("%.2f", $orderInfo['buy_money']),//订单总金额 元为单位 100.00 保留两位小数
//            "total_amount" => '0.01',               //订单总金额 元为单位 100.00 保留两位小数
            'passback_params' => UrlEncode('type=level'),
            "product_code" => '',                   //固定值
        ];

        return $this->payForm($bizContent, $type);
    }

    /**
     * 金币订单
     * @param $orderNumber
     * @param string $type
     * @return \common\pay\alipay\aop\提交表单HTML文本|string
     *
     */
    public function payCoin($orderNumber, $type = 'app') {

        $orderInfo = CoinRechargeOrder::getOneByWhere(['order_number' => $orderNumber]);
        $bizContent = [
            "body" => "龙邻生活。",               //对一笔交易的具体描述信息
            "subject" => "龙邻生活-金币充值",         //订单标题
            "out_trade_no" => $orderNumber,         //唯一平台订单号
            "total_amount" => sprintf("%.2f", $orderInfo['money']),//订单总金额 元为单位 100.00 保留两位小数
//            "total_amount" => '0.01',               //订单总金额 元为单位 100.00 保留两位小数
            'passback_params' => UrlEncode('type=coin'),
            "product_code" => '',                   //固定值
        ];

        return $this->payForm($bizContent, $type);
    }

    /**
     * 创建支付宝支付订单
     * @param array  $bizContent
     * @param string $type
     *
     * @return \common\pay\alipay\aop\提交表单HTML文本|string
     * @throws Exception
     */
    public function payForm($bizContent = [], $type = 'app') {
        $aop = new AopCertClient();
        $aop->gatewayUrl = $this->gatewayUrl;//网关
        $aop->appId = $this->app_id;//应用ID
        $aop->rsaPrivateKey = $this->merchant_private_key;//商户私钥  请填写开发者私钥去头去尾去回车，一行字符串
        $aop->alipayrsaPublicKey = $this->alipay_public_key;//支付宝公钥 请填写支付宝公钥，一行字符串
        $aop->apiVersion = $this->version;//版本号 固定值
        $aop->signType = $this->sign_type;  //签名方式
        $aop->postCharset = $this->charset;//编码格式
        $aop->format = $this->format;
        $aop->isCheckAlipayPublicCert = true;
        $aop->appCertSN = $aop->getCertSN($this->alipayAppPublicKeyCert); # 调用getCertSN获取证书序列号
        $aop->alipayRootCertSN = $aop->getRootCertSN($this->alipayRootKCert); # 调用getRootCertSN获取支付宝根证书序列号

        if (!array_key_exists($type,self::projectCodeMap)) {
            throw new Exception('支付类型不正确，请联系客服');
        }

        $projectCode = self::projectCodeMap[$type];

        $bizContent['product_code'] = $projectCode;

        $bizContent = json_encode($bizContent);

        switch ($type) {
            case 'app' :
                $request = new AlipayTradeAppPayRequest(); //APP支付需要这个
                //该处需要上传订单的信息
                $request->setNotifyUrl($this->notify_url);//设置回调地址
                $request->setReturnUrl($this->return_url);//设置通知地址
                $request->setBizContent($bizContent);
                $result = $aop->sdkExecute($request);
//                var_dump($result);die;
//                $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
//                var_dump($responseNode);die;
//                var_dump($result->$responseNode);die;
//                $resultCode = $result->$responseNode->code;
                break;
            case 'h5':
                $request = new AlipayTradeWapPayRequest(); //手机网站支付需要这个类
                //该处需要上传订单的信息
                $request->setNotifyUrl($this->notify_url);//设置回调地址
                $request->setReturnUrl($this->return_url);//设置通知地址
                $request->setBizContent($bizContent);
                $result = $aop->pageExecute ($request);
                break;
            default :
                $request = new AlipayTradePagePayRequest(); //电脑网站支付需要这个类
                //该处需要上传订单的信息
                $request->setNotifyUrl($this->notify_url);//设置回调地址
                $request->setReturnUrl($this->return_url);//设置通知地址
                $request->setBizContent($bizContent);
                $result = $aop->pageExecute ($request);
                break;
        }

        return $result;
    }

    /**
     * 创建支付宝支付订单
     * @param array  $bizContent
     * @param string $type
     *
     * @return \common\pay\alipay\aop\提交表单HTML文本|string
     * @throws Exception
     */
    public function payFormBak($bizContent = [], $type = 'app') {
        $aop = new AopClient();
        $aop->gatewayUrl = $this->gatewayUrl;//网关
        $aop->appId = $this->app_id;//应用ID
        $aop->rsaPrivateKey = $this->merchant_private_key;//商户私钥
        $aop->alipayrsaPublicKey = $this->alipay_public_key;//支付宝公钥
        $aop->apiVersion = $this->version;//版本号 固定值
        $aop->signType = $this->sign_type;  //签名方式
        $aop->postCharset = $this->charset;//编码格式
        $aop->format = $this->format;
        //        $aop->sign = $this->sign_type;  //如果使用SDK 则不需要签名。 自动生成签名

        if (!array_key_exists($type,self::projectCodeMap)) {
            throw new Exception('支付类型不正确，请联系客服');
        }

        $projectCode = self::projectCodeMap[$type];

        $bizContent['product_code'] = $projectCode;

        $bizContent = json_encode($bizContent);

        switch ($type) {
            case 'app' :
                $request = new AlipayTradeAppPayRequest(); //APP支付需要这个
                //该处需要上传订单的信息
                $request->setNotifyUrl($this->notify_url);//设置回调地址
                $request->setReturnUrl($this->return_url);//设置通知地址
                $request->setBizContent($bizContent);
                $result = $aop->sdkExecute($request);
//                var_dump($result);die;
                $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
                var_dump($responseNode);die;
                var_dump($result->$responseNode);die;
                $resultCode = $result->$responseNode->code;
                break;
            case 'h5':
                $request = new AlipayTradeWapPayRequest(); //手机网站支付需要这个类
                //该处需要上传订单的信息
                $request->setNotifyUrl($this->notify_url);//设置回调地址
                $request->setReturnUrl($this->return_url);//设置通知地址
                $request->setBizContent($bizContent);
                $result = $aop->pageExecute ($request);
                break;
            default :
                $request = new AlipayTradePagePayRequest(); //电脑网站支付需要这个类
                //该处需要上传订单的信息
                $request->setNotifyUrl($this->notify_url);//设置回调地址
                $request->setReturnUrl($this->return_url);//设置通知地址
                $request->setBizContent($bizContent);
                $result = $aop->pageExecute ($request);
                break;
        }

        return $result;
    }


    /**
     * 支付宝通知
     * @author fancy
     */
    public function notify() {
        $aop = new AopClient();
        $aop->alipayrsaPublicKey = $this->alipay_public_key;
        $post = Yii::$app->request->post();

        $content = "接收数据===记录时间".date('Y-m-d H:i:s')."\n";
        file_put_contents('/tmp/alipay_log.log', $content, FILE_APPEND);
        file_put_contents('/tmp/alipay_log.log', print_r($post,true), FILE_APPEND);

        $resSign = $aop->rsaCheckV1($post, null, $this->sign_type); //验证签名
        $trans = Yii::$app->db->beginTransaction();

        $passBackParams = isset($post['passback_params']) && !empty($post['passback_params']) ? trim($post['passback_params']) : ''; //公共回传参数
        $orderNumber = isset($post['out_trade_no']) && !empty($post['out_trade_no']) ? trim($post['out_trade_no']) : ''; //支付订单号
        $tradeStatus = isset($post['trade_status']) && !empty($post['trade_status']) ? trim($post['trade_status']) : ''; //交易状态
        $totalAmount = isset($post['total_amount']) && !empty($post['total_amount']) ? $post['total_amount'] : ''; //订单金额
        $payTime = isset($post['gmt_payment']) && !empty($post['gmt_payment']) ? $post['gmt_payment'] : ''; //交易付款时间

        try {
            //判断签名
            if(!$resSign) {
                throw new Exception('签名验证失败');
            }

            if (!$passBackParams) {
                throw new Exception('未知回传公共参数：未知订单类型');
            }

            $passBackParams = urldecode($passBackParams);
            parse_str($passBackParams,$passBackParamsArray);

            if (empty($passBackParamsArray['type'])) {
                throw new Exception('未知支付类型');
            }

            $type = trim($passBackParamsArray['type']); //订单类型

            $content = "订单类型======".date('Y-m-d H:i:s')."\n";
            file_put_contents('/tmp/alipay_log.log', $content, FILE_APPEND);
            file_put_contents('/tmp/alipay_log.log', print_r($passBackParamsArray,true), FILE_APPEND);
//            $content .= print_r($passBackParamsArray,true)."\n";

            //判断是否交易成功
            /**
             * TRADE_FINISHED   交易完成 不触发通知
             * TRADE_SUCCESS    支付成功 出发通知
             * WAIT_BUYER_PAY   交易创建 不触发通知
             * TRADE_CLOSED     交易关闭 出发通知
             */
            if($tradeStatus == 'TRADE_SUCCESS') {
                //写入交易成功的逻辑代码
                switch ($type) {
                    case 'goods':
                        $this->successGoods($orderNumber, $totalAmount, $payTime);
                        break;
                    case 'recharge':
                        $this->successRecharge($orderNumber, Status::PAY_WAY_ALIPAY, $payTime);
                        break;

                    case 'level':
                        $this->successLevel($orderNumber, $totalAmount, $payTime);
                        break;
                    case 'coin':
                        $this->successCoin($orderNumber, $totalAmount, $payTime);
                        break;
                }

            }
            $trans->commit();
            //记录日志
            $content = "======== SUCCESS =========\n";
            $content .= "订单号".$orderNumber.'===记录时间'.date('Y-m-d H:i:s')."\n";
            file_put_contents('/tmp/alipay_log.log', $content, FILE_APPEND);
//            file_put_contents('/tmp/alipay_log.log', $content, FILE_APPEND);
            return "success";
        } catch (Exception $e) {
            $trans->rollBack();
            //记录日志
            $content = "======== ERROR =========\n";
            $content .= "订单号".$orderNumber.'===失败原因'.$e->getMessage().'===记录时间'.date('Y-m-d H:i:s')."\n";
//            file_put_contents('/tmp/alipay_log.log', $content, FILE_APPEND);
            file_put_contents('/tmp/alipay_log.log', $content, FILE_APPEND);
            return "failure";
        }

    }

    /**
     * 商城订单
     * @param string $orderNumber
     * @param int $totalAmount
     * @param string $payTime
     * @throws Exception
     */
    public function successGoods($orderNumber = '', $totalAmount = 0, $payTime = '') {
        //订单处理
        (new GoodsOrder()) -> aliPaySuccess($orderNumber, $totalAmount, $payTime);
    }


    /**
     * 充值订单
     * @param string $orderNumber
     * @param int $payWay
     * @param string $payTime
     * @throws Exception
     */
    public function successRecharge($orderNumber = '', $payWay = 0, $payTime = '') {
        (new UserRechargeOrder()) -> success($orderNumber, $payWay, $payTime);
    }

    /**
     * 级别订单
     * @param string $orderNumber
     * @param int $totalAmount
     * @param string $payTime
     * @throws Exception
     */
    public function successLevel($orderNumber = '', $totalAmount = 0, $payTime = '') {
        (new UserLevelOrder()) -> aliPaySuccess($orderNumber, $totalAmount, $payTime);
    }

    /**
     * 金币订单
     * @param string $orderNumber
     * @param int $totalAmount
     * @param string $payTime
     * @throws Exception
     */
    public function successCoin($orderNumber = '', $totalAmount = 0, $payTime = '') {
        (new CoinRechargeOrder()) -> aliPaySuccess($orderNumber, $totalAmount, $payTime);
    }

    /**
     * 商城订单退款
     * @param $orderNumber
     * @return bool
     */
    public function refundGoods($orderNumber) {
        $orderInfo = GoodsOrder::getOneByWhere(['order_number' => $orderNumber]);
        $object = new stdClass();
        $object->out_trade_no = $orderNumber;                                   # 商户订单号。订单支付时传入的商户订单号，商家自定义且保证商家系统中唯一。与支付宝交易号 trade_no 不能同时为空。
        $object->refund_amount = sprintf("%.2f", $orderInfo['real_money']);     # 退款金额。该金额不能大于订单金额，单位为元，支持两位小数。
//        $object->trade_no = '2021081722001419121412730660'; # 支付宝交易号。和商户订单号 out_trade_no 不能同时为空。
        $queryRes = $this->queryTradeRefund($orderNumber);
        if (!$queryRes) {
            return $this->tradeRefund($object);
        }
        return true;
    }

    /**
     * 交易退款
     * @param $object
     * @return bool
     */
    public function tradeRefund($object) {
//        $aop = new AopClient ();
//
//        $aop->gatewayUrl = $this->gatewayUrl;//网关
//        $aop->appId = $this->app_id;//应用ID
//        $aop->rsaPrivateKey = $this->merchant_private_key;//商户私钥  请填写开发者私钥去头去尾去回车，一行字符串
//        $aop->alipayrsaPublicKey = $this->alipay_public_key;//支付宝公钥 请填写支付宝公钥，一行字符串
//        $aop->apiVersion = $this->version;//版本号 固定值
//        $aop->signType = $this->sign_type;  //签名方式
//        $aop->postCharset = $this->charset;//编码格式
//        $aop->format = $this->format;

        $aop = new AopCertClient();
        $aop->gatewayUrl = $this->gatewayUrl;//网关
        $aop->appId = $this->app_id;//应用ID
        $aop->rsaPrivateKey = $this->merchant_private_key;//商户私钥  请填写开发者私钥去头去尾去回车，一行字符串
        $aop->alipayrsaPublicKey = $this->alipay_public_key;//支付宝公钥 请填写支付宝公钥，一行字符串
        $aop->apiVersion = $this->version;//版本号 固定值
        $aop->signType = $this->sign_type;  //签名方式
        $aop->postCharset = $this->charset;//编码格式
        $aop->format = $this->format;
        $aop->isCheckAlipayPublicCert = true;
        $aop->appCertSN = $aop->getCertSN($this->alipayAppPublicKeyCert); # 调用getCertSN获取证书序列号
        $aop->alipayRootCertSN = $aop->getRootCertSN($this->alipayRootKCert); # 调用getRootCertSN获取支付宝根证书序列号

        //// 返回参数选项，按需传入
        //$queryOptions =[
        //   'refund_detail_item_list'
        //];
        //$object->query_options = $queryOptions;
        $json = json_encode($object);
        $request = new AlipayTradeRefundRequest();
        $request->setBizContent($json);
        $result = $aop->execute ( $request);
//        Yii::info($result,'退款信息');
        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $result->$responseNode->code;

//        $return['flag'] = true;
//        $return['msg'] = '退款成功';

        if(!empty($resultCode) && $resultCode == 10000){
//            $return['flag'] = true;
//            $return['msg'] = '退款成功';
//            echo "成功";
            return true;
        } else {
//            $return['flag'] = false;
//            $return['msg'] = $result->$responseNode->msg;
//            echo "失败";
            return false;
        }

//        return  $return;
    }

    // 查询退款接口
    public function queryTradeRefund($orderNumber) {
        $aop = new AopClient ();

        $aop->gatewayUrl = $this->gatewayUrl;//网关
        $aop->appId = $this->app_id;//应用ID
        $aop->rsaPrivateKey = $this->merchant_private_key;//商户私钥  请填写开发者私钥去头去尾去回车，一行字符串
        $aop->alipayrsaPublicKey = $this->alipay_public_key;//支付宝公钥 请填写支付宝公钥，一行字符串
        $aop->apiVersion = $this->version;//版本号 固定值
        $aop->signType = $this->sign_type;  //签名方式
        $aop->postCharset = $this->charset;//编码格式
        $aop->format = $this->format;

        $object = new stdClass();
        $object->out_trade_no = $orderNumber;
        $object->out_request_no = $orderNumber;
//// 返回参数选项，按需传入
//$queryOptions =[
//    'refund_detail_item_list'
//];
//$object->query_options = $queryOptions;
        $json = json_encode($object);
        $request = new AlipayTradeFastpayRefundQueryRequest();
        $request->setBizContent($json);
        $result = $aop->execute ( $request);
        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $result->$responseNode->code;

        $isRefund = false;

        // 判断是否退款
        $refundStatus = $result->$responseNode->refund_status;
        if(!empty($resultCode) && $resultCode == 10000){
            if(!empty($refundStatus) && $refundStatus == 'REFUND_SUCCESS'){
                $isRefund = true;
            }
        }

        return $isRefund;

    }


    /**
     * 用户提现
     * @param $orderNumber
     * @return bool
     */
    public function userWithdraw($orderNumber, $alipayAccount = "", $trueName = "") {
        $orderInfo = UserWithdrawOrder::getOneByWhere(['order_number' => $orderNumber]);
        $object = new stdClass();
        $object->out_biz_no = $orderNumber;                                   # 商户订单号。
        $object->trans_amount = sprintf("%.2f", $orderInfo['real_withdraw_money']);     # 订单总金额，单位为元，不支持千位分隔符，精确到小数点后两位，取值范围[0.1,100000000]。
        $object->product_code = "TRANS_ACCOUNT_NO_PWD";     # 销售产品码。单笔无密转账固定为 TRANS_ACCOUNT_NO_PWD。
        $object->biz_scene = "DIRECT_TRANSFER";     # 业务场景。单笔无密转账固定为 DIRECT_TRANSFER。
        $object->order_title = "代发转账";     # 转账业务的标题，用于在支付宝用户的账单里显示。
        $payeeInfo = [
            'identity' => $alipayAccount,//参与方的标识 ID。当 identity_type=ALIPAY_USER_ID 时，填写支付宝用户 UID。示例值：2088123412341234。当 identity_type=ALIPAY_LOGON_ID 时，填写支付宝登录号。示例值：186xxxxxxxx。
            'identity_type' => "ALIPAY_LOGON_ID",//参与方的标识类型，目前支持如下枚举：ALIPAY_USER_ID：支付宝会员的用户 ID，可通过 获取会员信息 能力获取。ALIPAY_LOGON_ID：支付宝登录号，支持邮箱和手机号格式。
            'name' => $trueName,//参与方真实姓名。如果非空，将校验收款支付宝账号姓名一致性。当 identity_type=ALIPAY_LOGON_ID 时，本字段必填。若传入该属性，则在支付宝回单中将会显示这个属性。
        ];
        $object->payee_info = $payeeInfo;     # 收款方信息
        return $this->fundTransUniTransfer($object);
//        $object->trade_no = '2021081722001419121412730660'; # 支付宝交易号。和商户订单号 out_trade_no 不能同时为空。
//        $queryRes = $this->queryTradeRefund($orderNumber);
//        if (!$queryRes) {
//            return $this->tradeRefund($object);
//        }
//        return true;
    }


    /**
     * 单笔转账接口
     * @param array $bizContent
     * @return bool|\SimpleXMLElement[]
     */
    public function fundTransUniTransfer($bizContent = []) {

        $alipayClient = new AopCertClient();
        $alipayClient->isCheckAlipayPublicCert = true;
        $alipayClient->gatewayUrl = $this->gatewayUrl; //网关
        $alipayClient->appId = $this->app_id; //应用ID
        $alipayClient->rsaPrivateKey =  $this->merchant_private_key;//商户私钥
        $alipayClient->format = $this->format; // 仅支持JSON
        $alipayClient->charset = $this->charset; //编码格式
        $alipayClient->signType = $this->sign_type; //签名方式
        //调用getPublicKey从支付宝公钥证书中提取公钥
        $alipayClient->alipayrsaPublicKey = $this->alipay_public_key;
        //是否校验自动下载的支付宝公钥证书，如果开启校验要保证支付宝根证书在有效期内
        $alipayClient->isCheckAlipayPublicCert = true;
        //调用getCertSN获取证书序列号
        $alipayClient->appCertSN = $alipayClient->getCertSN($this->alipayAppPublicKeyCert);
        //调用getRootCertSN获取支付宝根证书序列号
        $alipayClient->alipayRootCertSN = $alipayClient->getRootCertSN($this->alipayRootKCert);

        $request = new AlipayFundTransUniTransferRequest(); // 单笔转账接口
//        var_dump($bizContent);die;
        $bizContent = json_encode($bizContent);
        $request->setBizContent($bizContent);
        $responseResult = $alipayClient->execute($request);
        $responseApiName = str_replace(".","_",$request->getApiMethodName())."_response";
        $response = $responseResult->$responseApiName;
//        var_dump($response);die;
        Yii::info($response,'提现信息');
        if(!empty($response->code)&&$response->code==10000){
            return $response;
        } else {
          throw new Exception($response->sub_msg);
        }
    }

    /**
     * 转账业务单据查询接口
     * @param string $bizContent
     * @return bool|\SimpleXMLElement[]
     */
    public function queryFundTransUniTransfer($orderNumber = "") {
        $aopAlipayClient = new AopCertClient();
        $aopAlipayClient->gatewayUrl = $this->gatewayUrl;//网关
        $aopAlipayClient->appId = $this->app_id;//应用ID
        $aopAlipayClient->rsaPrivateKey = $this->merchant_private_key;//商户私钥
        $aopAlipayClient->format = $this->format;
        $aopAlipayClient->charset = $this->charset;//编码格式
        $aopAlipayClient->signType = $this->sign_type;  //签名方式
        $aopAlipayClient->apiVersion = $this->version;//版本号 固定值
        $aopAlipayClient->alipayrsaPublicKey = $this->alipay_public_key;//支付宝公钥
        $aopAlipayClient->isCheckAlipayPublicCert = true;
        $aopAlipayClient->appCertSN = $aopAlipayClient->getCertSN($this->alipayAppPublicKeyCert); # 调用getCertSN获取证书序列号
        $aopAlipayClient->alipayRootCertSN = $aopAlipayClient->getRootCertSN($this->alipayRootKCert); # 调用getRootCertSN获取支付宝根证书序列号
        //        $aop->sign = $this->sign_type;  //如果使用SDK 则不需要签名。 自动生成签名


        $request = new AlipayFundTransCommonQueryRequest();

        $bizContent = [
            'out_biz_no' => $orderNumber,
            'product_code' => "TRANS_ACCOUNT_NO_PWD",
            'biz_scene' => "DIRECT_TRANSFER",
        ];
        $bizContent = json_encode($bizContent);
        $request->setBizContent($bizContent);

//        $request->setBizContent("{".
////            "\"out_biz_no\":\"201808080001\",".
//            "\"order_id\":\"20190801110070000006380000250621\",".
////            "\"biz_scene\":\"PERSONAL_PAY\",".
////            "\"pay_fund_order_id\":\"20190801110070001506380000251556\",".
//            "\"product_code\":\"TRANS_ACCOUNT_NO_PWD\"".
//            "}");
        $responseResult = $aopAlipayClient->execute($request);
        $responseApiName = str_replace(".","_",$request->getApiMethodName())."_response";
        $response = $responseResult->$responseApiName;
//        var_dump($response);die;
        if(!empty($response->code)&&$response->code==10000){
            return $response;
        }
        else{
            return false;
        }

    }
}
